<?php

namespace Common\Model;

use Think\Model;

class QuestionModel extends Model
{
    protected $_validate = array(
        //array('title', 'require', '问题标题必须填写！', 1),//触屏端可以不填写标题
        array('category1', 'require', '请正确选择分类！', 1),
        array('category2', 'number', '请正确选择分类！', 2),
        array('reward', 'number', '悬赏参数错误！', 2),
        array('sms_remind', array(0, 1), '值的范围不正确！', 2, 'in'),
        array('anonymous', array(0, 1), '值的范围不正确！', 2, 'in'),
    );

    protected $_auto = array(
        array('issolve', '0'),
        array('click', '1'),
        array('audit', '0'),
        array('addtime', 'time', 1, 'function'),
    );

    /**
     * 获取问题列表
     *
     * @param array  $map  查询条件
     * @param bool   $page 是否分页
     * @param string $sort 排序规则
     * @param int    $num  获取条数
     * @return array
     */
    public function get_list($map = array(), $page = false, $sort = '', $num = 10, $startrow = 0)
    {
        $limit = $num ?: '10';
        if (empty($sort)) {
            $sort = "id DESC";
        }
        if ($page) {
            $count = $this->where($map)->count();
            $Page = pager($count, $limit);
            $limit = $Page->firstRow . ',' . $Page->listRows;
            $page_str = $Page->fshow();
            $list = $this->where($map)->order($sort)->limit($limit)->select();
        } else {
            $list = $this->where($map)->order($sort)->limit($startrow . ',' . $limit)->select();
        }

        if (empty($list)) return array();  // 返回空列表

        $list = array_map(array($this, 'fill'), $list);

        // 获取问题分类信息
        $cat = ytata_get_cache('cat');
        foreach ($list as $index => $question) {
            $_cat = $cat[$question['category2']];
            if (empty($_cat)) {
                $_cat = $cat[$question['category1']];
            }
            $list[$index]['cat'] = $_cat;
        }

        $return['list'] = $list;
        $return['page'] = $page_str;
        $return['count'] = $count ?: count($list);

        return $return;
    }

    /**
     * 添加问题
     * @param int $uid
     * @param array $data
     * @return array
     */
    public function question_add($uid, $data)
    {
        //检测是否禁言
        $ban = D('UserBan')->chenk_ban($uid);
        if (!empty($ban)) {
            $ret['status'] = false;
            $ret['msg'] = "发表失败，您已经被禁言（{$ban['txt']}），禁言结束时间：{$ban['endtime_str']}";
            return $ret;
        }

        $gold = 0;
        $sms_remind_val = C('YTATA_GOLD_SEND_MB');
        $sms_remind_val = intval($sms_remind_val);
        // 如果需要短信提醒
        if ($data['sms_remind'] == '1') {
            $save['sms_remind'] = 1;
            $gold += $sms_remind_val;
        } else {
            $save['sms_remind'] = 0;
        }
        //如果悬赏提问
        if ($data['reward_open'] == '1') {
            $save['reward'] = $data['reward'];
            $gold += $data['reward'];
        } else {
            $save['reward'] = 0;
        }
        $anonymous_val = C('YTATA_GOLD_QUANTIFIER_ANONYMOUS');
        $anonymous_val = intval($anonymous_val);
        //是否匿名
        if ($data['anonymous'] == '1') {
            $save['anonymous'] = 1;
            $gold += $anonymous_val;
        } else {
            $save['anonymous'] = 0;
        }

        $user = D('User')->get_user_one($uid);
        if (empty($user)) {
            $ret['status'] = false;
            $ret['msg'] = '用户不存在';
            return $ret;
        }
        // 判断用户gold是否够用
        if ($gold > $user['gold']) {
            $ret['status'] = false;
            $ret['msg'] = "发表失败，您的" . C('YTATA_GOLD_BYNAME') . "不够用了！";
            return $ret;
        } else {
            $save['uid'] = $user['uid'];
            $save['title'] = $data['title'];
            $save['category1'] = $data['category1'];
            $save['category2'] = $data['category2'];
            $save['describe'] = $data['describe'];
        }
        // 保存问题
        if (!$this->create($save)) {
            $ret['status'] = false;
            $ret['msg'] = $this->getError();
            return $ret;
        }
        $qid = $this->add();
        if (!$qid) {
            $ret['status'] = false;
            $ret['msg'] = '问题保存失败';
            return $ret;
        }
        // 插入图片
        $img = $data['img'];
        if (!empty($img)) {
            if (is_array($img)) {
                $qimg = M('QuestionImg');
                foreach ($img as $v) {
                    $map['qid'] = $qid;
                    $map['uid'] = $uid;
                    $map['img'] = $v;
                    $map['addtime'] = time();
                    $qimg->add($map);
                }
            }
        }
        //插入标签
        $tag = $data['tag'];
        if (!empty($tag)) {
            $count_tag = array();
            if (is_array($tag)) {
                foreach ($tag as $v) {
                    $map['qid'] = $qid;
                    $map['uid'] = $uid;
                    $_tag = D('Tag')->get_one_tag($v);
                    if (empty($_tag)) {
                        $data['tag'] = $v;
                        $data['addtime'] = time();
                        $tagid = M('Tag')->add($data);
                        $map['tagid'] = $tagid;
                    } else {
                        $map['tagid'] = $_tag['id'];
                    }
                    $map['tag'] = $v;
                    $count_tag[] = $map['tagid'];
                    M('QuestionTag')->add($map);
                }
            }
            //更新标签统计
            D('Tag')->set_tag_count($count_tag, 'count_question');
        }
        # 保存问题相关操作
        if ($data['sms_remind'] == '1') {
            D('User')->edit_user_gold(1, $uid, $sms_remind_val, '发表问题设置收到答案短信提醒', false);
        }
        if ($data['reward_open'] == '1') {
            D('User')->edit_user_gold(1, $uid, $data['reward'], '悬赏提问消耗', false);
        }
        if ($data['anonymous'] == '1') {
            D('User')->edit_user_gold(1, $uid, $anonymous_val, '匿名提问', false);
        }
        D('User')->update_count($uid, 1);//更新问题总数
        D('Task')->exe_add_question($uid);//完成发表问题的任务
        D('UserTrack')->add_track($uid, $qid, 1);//写入个人动态

        $ret['status'] = true;
        $ret['msg'] = '保存成功';
        $ret['qid'] = $qid;
        return $ret;
    }

    // 填充字段
    public function fill($item)
    {
        $item['title'] = trim($item['title']) ? $item['title'] : $item['describe'];
        $item['url'] = RU('question/view', array('id' => $item['id']));
        $item['answertimestr'] = daterange($item['answertime']);
        $item['addtimestr'] = daterange($item['addtime']);
        $item['qimg'] = isset($item['img']) ? 1 : 0;
        $item['describe_cut'] = cut_str(strip_tags($item['describe']), 80);
        foreach ($item['tags'] as $index => $q) {
            $item['tags'][$index]['tagurl'] = RU('tag/view', array('t' => $q['tagid']));
        }

        return $item;
    }

    /**
     * 设置排序类型
     *
     * @param int $type [1-0回答 2-高悬赏 3-已解决 4-未解决]
     * @return array
     */
    public function map_order($type)
    {
        $map = array();
        $type = (int)$type;

        switch ($type) {
            case 1:  // 0回答
                $map['answercount'] = 0;
                break;
            case 2:  // 高悬赏
                $map['issolve'] = 0;
                $map['reward'] = array('gt', 0);
                break;
            case 3:  // 已解决
                $map['issolve'] = 1;
                break;
            case 4:  // 未解决
                $map['issolve'] = 0;
                break;
        }

        return $map;
    }

    /**
     * 设置分类条件
     *
     * @param string $category1
     * @param string $category2
     * @return array
     */
    public function map_category($category1, $category2 = '')
    {
        $map = array();

        if ($category1 > 0) {
            $map['category1'] = $category1;
        }
        if ($category2 > 0) {
            $map['category2'] = $category2;
        }

        return $map;
    }

    /**
     * 设置审核类型
     * @param int $type [1-未审核 2-已审核 3-全部]
     */
    public function map_audit($type = 3)
    {
        $map = array();
        $case_type = array(
            1 => '0',
            2 => '1',
            3 => array('IN', array('0', '1'))
        );
        $map['audit'] = $case_type[$type];
        return $map;
    }

    /**
     * 设置关键词查询条件
     *
     * @param string $key_words
     * @return array
     */
    public function map_keywords($key_words, $key_type = 1)
    {
        $key_type = (int)$key_type;

        if ($key_type == 1) {
            $map['title'] = array('like', '%' . $key_words . '%');
        }
        if ($key_type == 2) {
            $map['describe'] = array('like', '%' . $key_words . '%');
        }
        if ($key_type == 3) {
            $map['uid'] = intval($key_words);
        }

        return $map;
    }

    /**
     * 设置问题 TAG 查询条件
     *
     * @param int $tag_id
     */
    public function map_tag($tag_id)
    {
        $ids = '';

        $tags = D('QuestionTag')->get_tag_tagid($tag_id);
        if (!empty($tags)) {
            $ids = array_column($tags, 'qid');
            $ids = implode(',', $ids);
        }

        $map['id'] = array('IN', $ids);

        return $map;
    }

    /**
     * 获取问题
     *
     * @param string $id
     * @param string $uid
     * @return mixed
     */
    public function get_question_one($id = '', $uid = '')
    {
        $map['id'] = intval($id);

        if (!empty($uid)) {
            $map['uid'] = intval($uid);
        }

        $info = $this->where($map)->find();
        $info['url'] = $this->view_url($info['id']);

        $info = $this->fill($info);

        return $info;
    }

    /**
     * 修改问题回答总数
     *
     * @param array|int $id
     * @return bool
     */
    public function edit_answercount($id)
    {
        $id = is_array($id) ? $id : array($id);

        foreach ($id as $v) {
            $map['id'] = intval($v);
            $map['answercount'] = D('Answer')->count_answer('', '', $v);
            $this->save($map);
        }

        return true;
    }

    /**
     * 修改点击次数
     *
     * @param string $id
     * @return bool
     */
    public function edit_click($id = '')
    {
        $map['id'] = intval($id);
        $this->where($map)->setInc('click', 1);
        return true;
    }

    /**
     * 修改悬赏数量
     *
     * @param string $id
     * @param string $gold
     * @return bool
     */
    public function edit_reward($id = '', $gold = '')
    {
        $map['id'] = intval($id);
        $this->where($map)->setInc('reward', $gold);
        return true;
    }

    /**
     * 修改问题回答用户
     *
     * @param string $id
     * @param string $uid
     * @param int    $answertime
     * @return bool
     */
    public function edit_answeruid($id = '', $uid = '', $answertime = null)
    {
        $map['id'] = intval($id);
        $map['answeruid'] = intval($uid);
        $map['answertime'] = isset($answertime) ? $answertime : time();
        $this->save($map);
        return true;
    }

    /**
     * 把问题设为已解决
     *
     * @param string $id
     * @return bool
     */
    public function set_solve($id = '')
    {
        $map['id'] = intval($id);
        $map['issolve'] = 1;
        $this->save($map);
        return true;
    }

    /**
     * 获取审核状态
     *
     * @param string $audit
     * @return string
     */
    public function get_audit($audit = '0')
    {
        switch ($audit) {
            case '0':
                $audit_str = '<span style="color:#FF0000">未审核</span>';
                break;
            case '1':
                $audit_str = '<span style="color:#009900">已审核</span>';
                break;
            case '-1':
                $audit_str = '<span style="color:#999999">未通过</span>';
                break;
        }
        return $audit_str;
    }

    /**
     * 获取问题总数
     *
     * @param int $uid
     * @return int
     */
    public function count_question($uid)
    {
        $map['uid'] = intval($uid);
        $map['audit'] = array('EGT', 0);
        return $this->where($map)->count();
    }

    /**
     * 删除问题
     *
     * @param array|string $ids 问题ID列表
     * @param int          $uid 问题所属用户ID
     * @return bool
     */
    public function del_question($ids, $uid = null)
    {
        if ($ids && preg_match("/^(\d{1,10},)*(\d{1,10})$/", $ids)) {
            $map['id'] = array('IN', "{$ids}");
            if (isset($uid)) {
                $map['uid'] = intval($uid);
            }
            $qlist = $this->where($map)->select();
            $this->where($map)->delete();
            $this->on_question_del($qlist);
            return true;
        }
    }

    /**
     * 删除问题事件处理
     *
     * @param array $qlist 删除问题列表
     */
    public function on_question_del($qlist)
    {
        $ids = array_column($qlist, 'id');

        $this->update_tags_question_count($ids);
        $map['qid'] = array('IN', "{$ids}");
        M('QuestionTag')->where($map)->delete();
        M('QuestionSupp')->where($map)->delete();
        M('QuestionImg')->where($map)->delete();
        $this->update_user_question_sum($qlist);
    }

    /**
     * 增加问题点赞数
     *
     * @param $uid
     * @param $qid
     * @return array
     */
    public function praise($uid, $qid)
    {
        $map['uid'] = $uid;
        $map['qid'] = $qid;
        $praise = M('QuestionPraise')->where($map)->find();
        if ($praise) {
            $res['status'] = 2;
            $res['msg'] = '已点过赞';
            return $res;
        }
        $ret = D('QuestionPraise')->praise_add($uid, $qid);
        // 点赞失败
        if (!$ret['status']) {
            $res['status'] = 0;
            $res['msg'] = $ret['msg'];
            return $res;
        }

        # 点赞成功相关操作
        $this->where(array('id' => $qid))->setInc('count_praise');  // 更新问题的点赞数
        $question = $this->find($qid);
        D('User')->inc_praise($question['uid']);  // 更新提问者被点赞总数
        D('Rank')->add_record('praise', $question['uid'], 1);

        $res['status'] = 1;
        $res['msg'] = $ret['msg'];
        $q = $this->field('count_praise')->find($qid);
        $res['count_praise'] = $q['count_praise'];
        return $res;
    }

    /**
     * 问题被关注
     * @param int $qid
     * @param int $uid
     * @return array
     */
    public function follow($qid, $uid)
    {
        $chenk = D('FollowQuestion')->chenk_follow_question($uid, $qid);
        if ($chenk) {
            D('FollowQuestion')->clear_follow_question($uid, $qid);
            # 用户取消关注问题相关操作

            $ajax['status'] = 2;
            $ajax['msg'] = '取消关注成功！';
            $ajax['count'] = D('FollowQuestion')->get_follow_count($qid);
            return $ajax;
        } else {
            D('FollowQuestion')->follow_question($uid, $qid);
            # 用户关注问题相关操作
            D('UserTrack')->add_track($uid, $qid, 6);//写入个人动态

            $ajax['status'] = 1;
            $ajax['count'] = D('FollowQuestion')->get_follow_count($qid);
            $ajax['msg'] = '关注成功！';
            return $ajax;
        }
    }

    /**
     * 获取详细页的URL
     *
     * @param $id
     * @return string
     */
    public function view_url($id)
    {
        return RU('question/view', array('id' => $id));
    }

    /**
     * 更新用户提问总数
     *
     * @param array $qlist 问题列表
     */
    protected function update_user_question_sum($qlist)
    {
        if ($qlist) {
            $uids = array_column($qlist, 'uid');
            $uids = array_unique($uids);
            D('User')->update_count($uids, 1);
        }
    }

    /**
     * 更新标签关联问题数统计[删除问题时]
     *
     * @param $ids
     */
    private function update_tags_question_count($ids)
    {
        //获取标签
        $tagmap['qid'] = array('IN', $ids);

        $tags = M('QuestionTag')->field('tagid')->where($tagmap)->select();
        if ($tags) {
            $set_tag = array_column($tags, 'tagid');
            //更新标签统计
            D('Tag')->set_tag_count($set_tag, 'count_question');
        }
    }
}